package net.minecraft.src;

public abstract class EntityPPHFlyingCreature extends EntityCreature
{

	public EntityPPHFlyingCreature(World world)
	{
		super(world);
	}
    
    public void onEntityDeath()
    {
    	int j = getDropItemQuantity();
    	if(j > 0)
    		dropItem(getDropItemId(), j);
    }
    
    public void onUpdate()
    {
    	if(health > 0 && health < 20)
    		health++;
    	if(hurtTime > 0)
    		hurtTime--;
    	onLivingUpdate();
    	/*if(idleTicks > 0)
    		idleTicks--;
    	else*/ if(health > 0)
    	{
    		moveEntity(motionX, motionY, motionZ);
    		faceCoords(randomX, randomY, randomZ);
    	}
    	if(health <= 0)
    	{
    		deathTime++;
            if(deathTime > 20)
            {
                onEntityDeath();
                setEntityDead();
                for(int k = 0; k < 20; k++)
                {
                    double d = rand.nextGaussian() * 0.02D;
                    double d1 = rand.nextGaussian() * 0.02D;
                    double d2 = rand.nextGaussian() * 0.02D;
                    worldObj.spawnParticle("explode", (posX + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, posY + (double)(rand.nextFloat() * height), (posZ + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, d, d1, d2);
                }

            }
    	}
    }
    
    protected void updateEntityActionState()
    {
    }
    
    public void onLivingUpdate()
    {
    	if(posY != 0) //Resolves a bug after restating the game!
    	{
    		if(spawnX == 0)
    		{
    			spawnX = posX;
    			spawnY = posY;
    			spawnZ = posZ;
    		}
    		if((int)posY == randomY || /*!canReach(posX, randomY, posZ) ||*/ randomY == 128)
    			newY();
    		/*else if(rand.nextInt(100) <= idleChance)
    		{
    			idleTicks = rand.nextInt(200);
    		}
    		*/else
    		{
    			if(posY > randomY)
    			{
    				motionY = -0.05F;
    				if(posY + motionY < randomY)
    					motionY = randomY - posY;
    			}
    			else
    			{
    				motionY = 0.05F;
    				if(posY + motionY > randomY)
    					motionY = randomY - posY;
    			}
    		}
    		if((int)posX == randomX || /*!canReach(randomX, posY, posZ) ||*/ randomX == 0)
    			newX();
    		/*else if(rand.nextInt(100) <= idleChance)
    		{
    			idleTicks = rand.nextInt(200);
    		}
    		*/else
    		{
    			if(posX > randomX)
    			{
    				motionX = -0.1F;
    				if(posX + motionX < randomX)
    					motionX = randomX - posX;
    			}
    			else
    			{
    				motionX = 0.1F;
    				if(posX + motionX > randomX)
    					motionX = randomX - posX;
    			}
    		}
    		if((int)posZ == randomZ || /*!canReach(posX, posY, posZ) ||*/ randomZ == 0)
    			newZ();
    		/*lse if(rand.nextInt(100) <= idleChance)
    		{
    			idleTicks = rand.nextInt(200);
    		}
    		*/else
    		{
    			if(posZ > randomZ)
    			{
    				motionZ = -0.1F;
    				if(posZ + motionZ < randomZ)
    					motionZ = randomZ - posZ;
    			}
    			else
    			{
    				motionZ = 0.1F;
    				if(posZ + motionZ > randomZ)
    					motionZ = randomZ - posZ;
    			}
    		}
        	if(rotationYaw < aimRotation)
        	{
        		if(rotationYaw + rotSpeed < aimRotation)
        			renderYawOffset = rotationYaw += rotSpeed;
        		else
        			renderYawOffset = rotationYaw = aimRotation;
        	}
        	else
        	{
        		if(rotationYaw - rotSpeed > aimRotation)
        			renderYawOffset = rotationYaw -= rotSpeed;
        		else
        			renderYawOffset = rotationYaw = aimRotation;
        	}
			//Commented this out since it was causing lag. -Will
    		//System.out.println((int)posY + " " + randomX + " " + randomY + " " + randomZ);
    	}
    }
    
    private void faceCoords(double x, double y, double z)
    {
    	prevRenderYawOffset = prevRotationYaw = renderYawOffset = rotationYaw;
    	double dX = x - posX;
    	double dZ = z - posZ;
    	if(dZ > 0)
    	{
    		if(dX > 0)
    			aimRotation = -45F;
    		else if(dX < 0)
    			aimRotation = 45F;
    		else
    			aimRotation = 0F;
    	}
    	else /*if(dZ < 0)*/
    	{
    		if(dX > 0)
    			aimRotation = 225F;
    		else if(dX < 0)
    			aimRotation = 135F;
    		else
    			aimRotation = 180F;
    	}
    }
	
    protected void newY()
	{
		if(inWater())
		{
			randomY = (int)posY + 5;
			return;
		}
		int floor = (int)posY - (int)distanceToSurface();
		randomY = 5 + floor + rand.nextInt(10);
	}
	
	protected void newX()
	{
		if(rXphase)
			randomX = (int)posX + 3 + rand.nextInt(10);
		else
			randomX = (int)posX - 3 - rand.nextInt(10);
		rXphase = !rXphase;
	}
	
	protected void newZ()
	{
		if(rZphase)
			randomZ = (int)posZ + rand.nextInt(25);
		else
			randomZ = (int)posZ - rand.nextInt(25);
		rZphase = !rZphase;
	}
	
	protected boolean canReach(double x, double y, double z)
	{
		return worldObj.getBlockId((int)x, (int)y, (int)z) != 0;
	}
	
	protected boolean isOnGround()
	{
		return distanceToSurface() < 1D;
	}
	
	protected double distanceToSurface()
	{
		int z = (int)posY;
		for(int i = z; i > 0; i--)
		{
			if(worldObj.getBlockId((int)posX, i, (int)posZ) != 0)
				return posY - i;
		}
		return -1;
	}
	
	protected int distanceToWater()
	{
		int z = (int)posY;
		for(int i = z; i > 0; i--)
		{
			if(worldObj.getBlockId((int)posX, i, (int)posZ) == Block.waterStill.blockID || worldObj.getBlockId((int)posX, i, (int)posZ) == Block.waterMoving.blockID)
				return z - i;
		}
		return -1;
	}
	
	public void writeEntityToNBT(NBTTagCompound nbttagcompound)
    {
		nbttagcompound.setDouble("spawnX", spawnX);
		nbttagcompound.setDouble("spawnY", spawnY);
		nbttagcompound.setDouble("spawnZ", spawnZ);
        super.writeEntityToNBT(nbttagcompound);
    }

    public void readEntityFromNBT(NBTTagCompound nbttagcompound)
    {
    	spawnX = nbttagcompound.getDouble("spawnX");
    	spawnY = nbttagcompound.getDouble("spawnY");
    	spawnZ = nbttagcompound.getDouble("spawnZ");
        super.readEntityFromNBT(nbttagcompound);
    }
	
	protected boolean inWater()
	{
		return worldObj.getBlockId((int)posX, (int)posY, (int)posZ) == Block.waterStill.blockID || worldObj.getBlockId((int)posX, (int)posY, (int)posZ) == Block.waterMoving.blockID;
	}
	
	protected void setMob(float rotationSpeed, int idleRate)
	{
		rotSpeed = rotationSpeed;
		idleChance = idleRate;
	}
	
	protected abstract int getDropItemQuantity();
	
    /* Movement Properties */
    int randomY = 128;
    int randomX = 0;
    int randomZ = 0;
    boolean rXphase = true;
    boolean rZphase = false;
    boolean rYphase = false;
    float rotSpeed = 5F;
    float aimRotation = 0F;
    
    /* Idle Properties */
    int idleTicks = 0;
    int idleChance = 0;
    
    /* Spawn Properties */
    double spawnX;
    double spawnZ;
    double spawnY;

}